﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsTest
{
    class DeleteLine
    {
        public static Bitmap GetImageWithoutLine(byte[,] im)
        {
            var w = im.GetLength(0);
            var h = im.GetLength(1);
            var linePoints = getTheLinePoint(im, w, h, 8);
            im = deletePoints(im, linePoints);
            var bmNew = Common.ToBitmap(im);
            return bmNew;
        }

        private static List<int[]> getTheLinePoint(byte[,] im, int w, int h, int space)
        {
            unsafe
            {
                var linePoints = new List<int[]>();
                var tempPoints = new List<int[]>();
                fixed (byte* ptr = &im[0, 0])
                {
                    for (int j = 1; j < h - 1; j++)
                    {
                        for (int i = 1; i < w - space; i++)
                        {
                            //将线上的点放入集合
                            var p = ptr + j * w + i;
                            if (*p == 1)
                            {
                                var flag = true;
                                var y = j;
                                while (flag)
                                {
                                    i++;
                                    if (i > w - space - 1) break;
                                    flag = false;
                                    if (im[i, y] == 1)
                                    {
                                        flag = true;
                                        tempPoints.Add(new[] { i, y });
                                    }
                                    else
                                    {
                                        if (y - 1 > 1 && im[i, y - 1] == 1)
                                        {
                                            flag = true;
                                            y = y - 1;
                                            tempPoints.Add(new[] { i, y });
                                            continue;
                                        }

                                        if (y + 1 < h - 1 && im[i, y + 1] == 1)
                                        {
                                            flag = true;
                                            y = y + 1;
                                            tempPoints.Add(new[] { i, y });
                                            continue;
                                        }

                                        for (int k = space; k > 0; k--)
                                        {
                                            if (im[i + k, y] == 1)
                                            {
                                                flag = true;
                                                i = i + k;
                                                tempPoints.Add(new[] { i, y });
                                                break;
                                            }

                                            if (y - 1 > 1 && im[i + k, y - 1] == 1)
                                            {
                                                flag = true;
                                                y = y - 1;
                                                i = i + k;
                                                tempPoints.Add(new[] { i, y });
                                                break;
                                            }

                                            if (y + 1 < h - 1 && im[i + k, y + 1] == 1)
                                            {
                                                flag = true;
                                                y = y + 1;
                                                i = i + k;
                                                tempPoints.Add(new[] { i, y });
                                                break;
                                            }
                                        }
                                    }
                                }

                                if (tempPoints.Count > 64)
                                {
                                    tempPoints = complete(im, tempPoints);
                                    linePoints.AddRange(tempPoints);
                                }
                            }
                        }
                        tempPoints = new List<int[]>();
                    }
                }
                return linePoints;
            }
        }

        private static byte[,] deletePoints(byte[,] im, List<int[]> linePoints)
        {
            foreach (var point in linePoints)
            {
                im[point[0], point[1]] = 0;
            }
            return im;
        }

        private static List<int[]> complete(byte[,] im, List<int[]> tempPoints)
        {
            var temp = new List<int[]>();
            for (int i = 0; i < tempPoints.Count; i++)
            {
                for (int k = -1; k < 2; k++)
                {
                    for (int l = -1; l < 2; l++)
                    {
                        if (im[tempPoints[i][0] + k, tempPoints[i][1] + l] == 1)
                        {
                            var ints = new[] { tempPoints[i][0] + k, tempPoints[i][1] + l };
                            if (!temp.Exists(p => p == ints))
                            {
                                temp.Add(ints);
                            }
                        }
                    }
                }
            }
            if(temp.Any())
            {
                tempPoints.AddRange(temp);
            }
            return tempPoints;
        }

        private static void test(byte[,] im, int w, int h)
        {

        }
    }
}
